// 实现这个项目的构建任务

// series-串型执行，parallel-并行执行
const { src, dest, series, parallel, watch } = require('gulp');

const del = require('del');
const bs = require('browser-sync').create();
const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();
const mockData = require('./mockData');

// 基本任务格式
// const taskname = () => {
//   return src('src/*.js').pipe(babel()).pipe(dest('output/'));
// }

const clean = () => {
  return del('temp', 'dist');
}

// 编译sass（不压缩）
const sass = plugins.sass(require('sass'));
const buildSass = () => {
  console.log('buildSass');
  return src('src/assets/styles/*.scss', { base: 'src' })
    .pipe(sass())
    .pipe(dest('temp'))
    // .pipe(bs.reload({ stream: true }))
    .pipe(bs.stream())
}

// 编译js（不压缩）
const buildJs = () => {
  console.log('buildJs');
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({
      presets: ['@babel/env']
    }))
    .pipe(dest('temp'))
    // .pipe(bs.reload({ stream: true }))
    .pipe(bs.stream())
}

// 编译html（解析ejs，不压缩）
const buildHtml = () => {
  console.log('buildHtml');
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data: mockData, defaults: { cache: false }}))
    .pipe(dest('temp'))
    // .pipe(bs.reload({ stream: true }))
    .pipe(bs.stream())
}

// 编译Sass,JS,Html
const compile = series(
  clean,
  parallel(buildSass,buildJs,buildHtml)
);

// 图片和字体压缩
const imageAndFont = () => {
  return src(['src/assets/images/**', 'src/assets/fonts/**'], { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

// public文件直接拷贝
const pubilc = () => {
  return src('src/assets/pubilc/**', { base: 'pubilc' })
    .pipe(dest('dist'))
}

// 服务器初始化
const serverInit = () => {
  watch('src/assets/styles/*.scss', buildSass)
  watch('src/assets/scripts/*.js', buildJs)
  watch('src/*.html', buildHtml)
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)

  bs.init({
    port: 3333,
    server: {
      baseDir: ['temp', 'public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

// 处理文件引用，压缩产出的文件
const useref = () => {
  return src('temp/*.html').pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest('dist'))
}

// 文件验证
const eslint = plugins.eslint;
const lint = () => {
  return src(['src/assets/scripts/*.js'])
      .pipe(eslint())
      .pipe(eslint.format())
      .pipe(eslint.failAfterError());
}

// 打包功能，暴露给外层调用
const build = series(
  lint,
  clean,
  parallel(
    series(compile, useref),
    imageAndFont,
    pubilc
  )
);

// 启动开发服务器，暴露给外层调用
const serve = series(
  compile,
  serverInit
)

module.exports = {
  clean,
  lint,
  serve,
  build
}
